<html>
<head><meta charset="utf-8"><title>typic · project-safe-transmute · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/index.html">project-safe-transmute</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html">typic</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="184458872"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184458872" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184458872">(Dec 30 2019 at 08:38)</a>:</h4>
<p>Worth reviewing: <a href="https://github.com/jswrenn/typic" target="_blank" title="https://github.com/jswrenn/typic">https://github.com/jswrenn/typic</a></p>



<a name="184492266"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184492266" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184492266">(Dec 30 2019 at 18:53)</a>:</h4>
<p>I'm happy to answer questions about it!</p>



<a name="184558390"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184558390" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184558390">(Dec 31 2019 at 18:25)</a>:</h4>
<p>Based on <span class="user-mention" data-user-id="219211">@Jack Wrenn</span>'s amazing work on <code>typic</code>, I created <code>chtrans</code> (checked transmute)</p>
<p><a href="https://github.com/KrishnaSannasi/chtrans" target="_blank" title="https://github.com/KrishnaSannasi/chtrans">https://github.com/KrishnaSannasi/chtrans</a></p>



<a name="184558391"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184558391" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184558391">(Dec 31 2019 at 18:25)</a>:</h4>
<p>A few notable differences, I fully support non-zero types, bool, but I have less support for references right now. (Although I could support references in the same way as <code>typic</code> with minor changes).<br>
There are numerous implementation differences, such as removing references as slots, a custom backwards linked list (which made some other parts easier/cheaper to implement).</p>



<a name="184558482"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184558482" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184558482">(Dec 31 2019 at 18:27)</a>:</h4>
<p>All this without a huge amount of special casing (such as in <code>typic::transmutation</code>), this is due to a new idea I'm calling <code>Marker</code>. <code>Marker</code>s are properties that can be searched for and must be validated. For example, <code>NonZero&lt;N&gt;</code> is the property that the next <code>N</code> bytes when interpreted as an integer is non-zero</p>



<a name="184558662"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184558662" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184558662">(Dec 31 2019 at 18:30)</a>:</h4>
<p>My hope was to spur experimentation in this area, so I'm thrilled to have been a source of inspiration. :D I can't wait to dig into your approach!</p>



<a name="184558685"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184558685" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184558685">(Dec 31 2019 at 18:30)</a>:</h4>
<p>It was really eye opening to see your implementation, I loved digging through it!</p>



<a name="184558707"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184558707" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184558707">(Dec 31 2019 at 18:31)</a>:</h4>
<p>It reminded me of when I first  began to understand typenum.</p>



<a name="184558823"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184558823" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184558823">(Dec 31 2019 at 18:33)</a>:</h4>
<p>One limitation that I am now realizing is the handling of privacy, right now if you apply <code>chtrans::repr</code>, you are implicitly making your type transparent. I need to find a way around this. I also don't support fallible transmute just yet. I suspect these two are related.</p>



<a name="184559026"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184559026" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184559026">(Dec 31 2019 at 18:37)</a>:</h4>
<p>Re privacy, did you see this: <a href="https://github.com/jswrenn/typic/blob/master/typic/tests/invariants_opaque.rs" target="_blank" title="https://github.com/jswrenn/typic/blob/master/typic/tests/invariants_opaque.rs">https://github.com/jswrenn/typic/blob/master/typic/tests/invariants_opaque.rs</a><br>
In my approach, a type is only transparent if all fields are marked <code>pub</code>.</p>



<a name="184559096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184559096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184559096">(Dec 31 2019 at 18:38)</a>:</h4>
<p>Yes, I was just getting to that. That's what reminded me of this problem.</p>



<a name="184559356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184559356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184559356">(Dec 31 2019 at 18:42)</a>:</h4>
<p>For checking invariants, would it be fine if we just created the type then passed it to <code>Invariants::check</code>, and leaking it if the check fails? That way we don't need to generate at <code>Candidate</code> type (which looks like it is semantically doing the same thing). I'm not sure if the is sound, but it might be simpler to implement.</p>



<a name="184559588"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184559588" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184559588">(Dec 31 2019 at 18:47)</a>:</h4>
<p>Maybe? The <code>Candidate</code> is a doppelganger of the type but without any methods, since methods on the original type might rely on inter-field invariants. My first approach at this did what you describe, but the soundness issue lead me to move away from it.</p>



<a name="184559680"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184559680" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184559680">(Dec 31 2019 at 18:49)</a>:</h4>
<p>cc <span class="user-mention" data-user-id="120791">@RalfJ</span></p>



<a name="184612696"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184612696" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184612696">(Jan 01 2020 at 20:41)</a>:</h4>
<p>Following up on my assertion that supporting <code>union</code> was 'just' a matter of adding the layout algorithm for them, the <code>unions</code> branch of Typic now provides a proof-of-concept implementation. Example here: <a href="https://github.com/jswrenn/typic/blob/unions/typic/tests/unions.rs" target="_blank" title="https://github.com/jswrenn/typic/blob/unions/typic/tests/unions.rs">https://github.com/jswrenn/typic/blob/unions/typic/tests/unions.rs</a></p>
<p>To encode which unions are layout compatible, I needed my first nightly feature: <code>marker_trait_attr</code>. (Namely, to state that  a<code>UA</code> can be transmuted into a <code>UB</code> if every variant of <code>UA</code> can be transmuted into  _any_ variant of <code>UB</code>.) So, that's an unfortunate barrier for making this functionality available as a library.</p>



<a name="184613537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184613537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184613537">(Jan 01 2020 at 21:04)</a>:</h4>
<p>I added <code>MaybeUninit</code>, but I need to add full union support. (This shouldn't be too hard, similarly to you it is just extending the macro, and adding the layout algorithm)</p>
<p>On the note of <code>Candidate</code>, I found this in the UCG</p>
<p><a href="https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/glossary.md#validity-and-safety-invariant" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/glossary.md#validity-and-safety-invariant">https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/glossary.md#validity-and-safety-invariant</a></p>
<blockquote>
<p>The safety invariant is an invariant that safe code may assume all data to uphold. This invariant is used to justify which operations safe code can perform. The safety invariant can be temporarily violated by unsafe code, but must always be upheld when interfacing with unknown safe code. It is not relevant when arguing whether some program has UB, but it is relevant when arguing whether some code safely encapsulates its unsafety -- in other words, it is relevant when arguing whether some library is sound.</p>
</blockquote>
<p>So I think it is fine to forge an possibly invalid type as long as it doesn't break any validity invariants, like references must always be aligned.  Library invariants don't matter (like <code>Foo.x</code> can never be odd, or <code>Vec.len</code> must not cover uninitialized data. So long as you don't expose this to safe code. Which we don't, only exposed to the <code>Invariants</code> trait, which is <code>unsafe</code> to implement.</p>



<a name="184614723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184614723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184614723">(Jan 01 2020 at 21:42)</a>:</h4>
<p><span class="user-mention" data-user-id="202379">@Yato</span> I just pushed to the <code>enums</code> branch with proof-of-concept support of <code>enum</code>.</p>
<p>I desugar enums to equivalent unions according to <a href="https://rust-lang.github.io/rfcs/2195-really-tagged-unions.html" target="_blank" title="https://rust-lang.github.io/rfcs/2195-really-tagged-unions.html">RFC#2195</a> and use my existing <code>union</code> layout machinery.  Discriminants are represented using const generics. See: <a href="https://github.com/jswrenn/typic/blob/enums/typic/tests/enums.rs" target="_blank" title="https://github.com/jswrenn/typic/blob/enums/typic/tests/enums.rs">https://github.com/jswrenn/typic/blob/enums/typic/tests/enums.rs</a></p>



<a name="184614801"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184614801" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184614801">(Jan 01 2020 at 21:46)</a>:</h4>
<p>And with that, I'm thrilled to have confirmed my suspicion that Rust's type system is already expressive enough to reasonably enforce every statically-checkable transmutation I can think of! ^_^</p>



<a name="184614988"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184614988" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184614988">(Jan 01 2020 at 21:51)</a>:</h4>
<p>Caveat for onlookers: this is totally Research Quality™. I haven't yet closely reviewed my low-level layout compatibility checks to make sure I haven't accidentally permitted something I meant to forbid (which is as easy as leaving off a trait bound) or omitted an impl for a transition I meant to allow (in fact, I've definitely omitted impls).</p>



<a name="184616983"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184616983" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184616983">(Jan 01 2020 at 22:55)</a>:</h4>
<p>Same caveat applies to <code>chtrans</code></p>



<a name="184617036"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184617036" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184617036">(Jan 01 2020 at 22:57)</a>:</h4>
<p>One thing I was thinking about wrt unions, are unions allowed to contain uninitialized bytes anywhere in their layout</p>
<p>i.e. is this allowed to be uninitialized</p>
<div class="codehilite"><pre><span></span><span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">union</span> <span class="nc">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">value</span>: <span class="kt">i32</span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="184617099"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184617099" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184617099">(Jan 01 2020 at 22:59)</a>:</h4>
<p>Unless those bytes are introduced by a variant: no. <code>MaybeUninit&lt;i32&gt;</code> cannot be transmuted to <code>Foo</code>, because <code>Foo</code>'s valid bit pattern is identical to <code>i32</code> (i.e., four arbitrarily initialized bytes).</p>



<a name="184617245"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184617245" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184617245">(Jan 01 2020 at 23:03)</a>:</h4>
<p>This seems to be related to<br>
<a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/73" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/73">https://github.com/rust-lang/unsafe-code-guidelines/issues/73</a><br>
<a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/156" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/156">https://github.com/rust-lang/unsafe-code-guidelines/issues/156</a></p>



<a name="184617539"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184617539" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184617539">(Jan 01 2020 at 23:10)</a>:</h4>
<p>Huh. Regarding <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/73" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/73">#73</a>, I find it very surprising that there could be a valid bit pattern for a union <code>T</code> that wasn't a valid bit pattern for any of <code>T</code>'s variants.</p>



<a name="184617609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184617609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184617609">(Jan 01 2020 at 23:12)</a>:</h4>
<p>Off the top of my head, it seems like that would pose a significant barrier to providing a mechanism for safe variant access. E.g., it's completely impossible to provide a safe accessor for <code>value</code> in your example, because a valid instance of<code>Foo</code> could have been constructed from uninitialized bits.</p>



<a name="184617694"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184617694" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184617694">(Jan 01 2020 at 23:15)</a>:</h4>
<p>Yes, that's why I asked. As I was going through the UCG's guidelines I came across <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/73" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/73">#73</a> and that surprised me. For now, I will implement unions as a sequence of uninitialized bytes, just to be safe.</p>
<p>Here is the motivating example for unions having byte patterns that fit non of the variants from another thread<br>
<a href="https://github.com/rust-lang/rust/issues/32836#issuecomment-408766424" target="_blank" title="https://github.com/rust-lang/rust/issues/32836#issuecomment-408766424">https://github.com/rust-lang/rust/issues/32836#issuecomment-408766424</a></p>



<a name="184617950"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184617950" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184617950">(Jan 01 2020 at 23:23)</a>:</h4>
<p>The current rule I have basically this: <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/73#issuecomment-504060109" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/73#issuecomment-504060109">https://github.com/rust-lang/unsafe-code-guidelines/issues/73#issuecomment-504060109</a></p>



<a name="184618061"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618061" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618061">(Jan 01 2020 at 23:26)</a>:</h4>
<p>There's some discussion of niche-finding optimizations in that issue. AFAIK, those considerations don't affect us because niche finding can't reach into <code>#[repr(C)]</code> types to find niches.</p>
<p>(At least, that's my understanding from <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/174" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/174">#174</a>.)</p>



<a name="184618169"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618169" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618169">(Jan 01 2020 at 23:30)</a>:</h4>
<p>Ok, I'm going to ask there just to make sure, I don't really want to speculate on this.</p>



<a name="184618225"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618225" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618225">(Jan 01 2020 at 23:32)</a>:</h4>
<p>Layout optimizations does matter for your implementation of enums, wrt <code>Option</code>-like enums, but not wrt unions</p>



<a name="184618279"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618279" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618279">(Jan 01 2020 at 23:34)</a>:</h4>
<p>I haven't tried to implement any layout computations for <code>#[repr(Rust)]</code> enums (and probably won't attempt it). There aren't any tricky layout optimizations on <code>#[repr(C)]</code> enums.</p>



<a name="184618349"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618349" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618349">(Jan 01 2020 at 23:36)</a>:</h4>
<p>It looks like this doesn't work?</p>
<div class="codehilite"><pre><span></span><span class="cp">#[typic::repr(C, _)]</span><span class="w"></span>
<span class="k">enum</span> <span class="nc">OptionLike</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">Bool</span><span class="p">(</span><span class="kt">bool</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">Empty</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>So just <code>C</code>-like enums then?</p>



<a name="184618464"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618464" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618464">(Jan 01 2020 at 23:40)</a>:</h4>
<p>What do you mean by "work"? <code>OptionLike</code> is <code>repr(C)</code>, so we can compute the layout of it without doing any niche finding optimizations. It should be eight bytes. If it weren't <code>repr(C)</code>, then it'd only be one byte.</p>



<a name="184618607"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618607" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618607">(Jan 01 2020 at 23:45)</a>:</h4>
<p>Right now that doesn't compile with <code>typic</code> (regardless of what integer type I put in the <code>_</code>)</p>



<a name="184618676"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618676" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618676">(Jan 01 2020 at 23:47)</a>:</h4>
<p>Oops. It "works" in "theory". ;) Tbh, I committed after getting discriminants to work and didn't write any test cases for variants with fields. Let me see what I forgot...</p>



<a name="184618727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618727">(Jan 01 2020 at 23:48)</a>:</h4>
<p>I get these errors,</p>
<div class="codehilite"><pre><span></span><span class="n">error</span>: <span class="nc">reaching</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">expression</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">runtime</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">panic</span><span class="w"> </span><span class="n">or</span><span class="w"> </span><span class="n">abort</span><span class="w"></span>
<span class="w">  </span><span class="o">-</span>-&gt; <span class="nc">typic</span><span class="err">\</span><span class="n">tests</span><span class="err">\</span><span class="n">enums</span><span class="p">.</span><span class="n">rs</span>:<span class="mi">24</span>:<span class="mi">1</span><span class="w"></span>
<span class="w">   </span><span class="o">|</span><span class="w"></span>
<span class="mi">24</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="cp">#[typic::repr(C)]</span><span class="w"></span>
<span class="w">   </span><span class="o">|</span><span class="w"> </span><span class="o">^^^^^^^^^^^^^^^^^</span><span class="w"> </span><span class="s">&quot;pointer-to-integer cast&quot;</span><span class="w"> </span><span class="n">needs</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">rfc</span><span class="w"> </span><span class="n">before</span><span class="w"> </span><span class="n">being</span><span class="w"> </span><span class="n">allowed</span><span class="w"> </span><span class="n">inside</span><span class="w"> </span><span class="n">constants</span><span class="w"></span>
<span class="w">   </span><span class="o">|</span><span class="w"></span>
<span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">note</span>: <span class="err">`</span><span class="cp">#[deny(const_err)]</span><span class="err">`</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">by</span><span class="w"> </span><span class="n">default</span><span class="w"></span>

<span class="n">error</span><span class="p">[</span><span class="n">E0080</span><span class="p">]</span>: <span class="nc">evaluation</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">constant</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="n">failed</span><span class="w"></span>
<span class="w">  </span><span class="o">-</span>-&gt; <span class="nc">typic</span><span class="err">\</span><span class="n">tests</span><span class="err">\</span><span class="n">enums</span><span class="p">.</span><span class="n">rs</span>:<span class="mi">24</span>:<span class="mi">1</span><span class="w"></span>
<span class="w">   </span><span class="o">|</span><span class="w"></span>
<span class="mi">24</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="cp">#[typic::repr(C)]</span><span class="w"></span>
<span class="w">   </span><span class="o">|</span><span class="w"> </span><span class="o">^^^^^^^^^^^^^^^^^</span><span class="w"> </span><span class="n">referenced</span><span class="w"> </span><span class="n">constant</span><span class="w"> </span><span class="n">has</span><span class="w"> </span><span class="n">errors</span><span class="w"></span>

<span class="n">error</span><span class="p">[</span><span class="n">E0605</span><span class="p">]</span>: <span class="nc">non</span><span class="o">-</span><span class="n">primitive</span><span class="w"> </span><span class="n">cast</span>: <span class="err">`</span><span class="n">OptionLike</span><span class="err">`</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="err">`</span><span class="kt">isize</span><span class="err">`</span><span class="w"></span>
<span class="w">  </span><span class="o">-</span>-&gt; <span class="nc">typic</span><span class="err">\</span><span class="n">tests</span><span class="err">\</span><span class="n">enums</span><span class="p">.</span><span class="n">rs</span>:<span class="mi">24</span>:<span class="mi">1</span><span class="w"></span>
<span class="w">   </span><span class="o">|</span><span class="w"></span>
<span class="mi">24</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="cp">#[typic::repr(C)]</span><span class="w"></span>
<span class="w">   </span><span class="o">|</span><span class="w"> </span><span class="o">^^^^^^^^^^^^^^^^^</span><span class="w"></span>
<span class="w">   </span><span class="o">|</span><span class="w"></span>
<span class="w">   </span><span class="o">=</span><span class="w"> </span><span class="n">note</span>: <span class="nc">an</span><span class="w"> </span><span class="err">`</span><span class="k">as</span><span class="err">`</span><span class="w"> </span><span class="n">expression</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">used</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="n">between</span><span class="w"> </span><span class="n">primitive</span><span class="w"> </span><span class="n">types</span><span class="p">.</span><span class="w"> </span><span class="n">Consider</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="err">`</span><span class="nb">From</span><span class="err">`</span><span class="w"> </span><span class="k">trait</span><span class="w"></span>
</pre></div>



<a name="184618735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618735">(Jan 01 2020 at 23:48)</a>:</h4>
<p>HUH. Ohhhhh. D'oh.</p>



<a name="184618744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618744">(Jan 01 2020 at 23:49)</a>:</h4>
<p>I forgot you can't use <code>as</code> on non-fieldless variants.<br>
This is the problematic line: <a href="https://github.com/jswrenn/typic/blob/644d264e9cc22ad63b011532ffff07ee6e6fe7fe/typic-derive/src/lib.rs#L173" target="_blank" title="https://github.com/jswrenn/typic/blob/644d264e9cc22ad63b011532ffff07ee6e6fe7fe/typic-derive/src/lib.rs#L173">https://github.com/jswrenn/typic/blob/644d264e9cc22ad63b011532ffff07ee6e6fe7fe/typic-derive/src/lib.rs#L173</a></p>



<a name="184618868"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184618868" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184618868">(Jan 01 2020 at 23:53)</a>:</h4>
<p><del>Yeah, that's going to be slightly inconvenient to work around, but nothing major.</del> (I'd love to see an RFC for safely accessing the discriminants of non-fieldless variants!)</p>
<p>EDIT: That's going to be a pain to work around. It's not a theoretical limitation or anything, there's just no easy way to get the discriminant out of a variant without constructing an instance of the variant. I have an idea of how to do it, but it's a bunch of dreadful extra work on the automatic derive that I'm not eager to do tonight. :(</p>



<a name="184620789"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184620789" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184620789">(Jan 02 2020 at 00:56)</a>:</h4>
<p><span class="user-mention" data-user-id="202379">@Yato</span>: Give things a shot, now. I found a workaround that wasn't as painful as I was expecting. :)</p>



<a name="184660528"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184660528" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> James Munns <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184660528">(Jan 02 2020 at 15:48)</a>:</h4>
<p><span class="user-mention" data-user-id="219211">@Jack Wrenn</span> I think <span class="user-mention" data-user-id="215333">@Florian Gilcher</span> had an RFC for this (a [const] function that gets you the ID of the variant)</p>



<a name="184660655"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184660655" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> James Munns <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184660655">(Jan 02 2020 at 15:50)</a>:</h4>
<p>Ah, wrong on two counts. It was only to get the <em>size</em> of the discriminant in bits, and it was closed without merging: <a href="https://github.com/rust-lang/rfcs/pull/2684" target="_blank" title="https://github.com/rust-lang/rfcs/pull/2684">https://github.com/rust-lang/rfcs/pull/2684</a></p>



<a name="184665071"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184665071" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184665071">(Jan 02 2020 at 16:48)</a>:</h4>
<p><span class="user-mention" data-user-id="202379">@Yato</span> </p>
<blockquote>
<p>I think it is fine to forge an possibly invalid type as long as it doesn't break any validity invariants</p>
</blockquote>
<p>That sounds a bit funny? "It can be invalid as long as it's valid"?^^<br>
but it is fine to forge a value violating the <em>safety</em> invariant as long as it does not violate the <em>validity</em> invariant</p>



<a name="184665095"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184665095" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184665095">(Jan 02 2020 at 16:49)</a>:</h4>
<p>@RalfJ Sorry, got my terms mixed up, but that's what I meant</p>



<a name="184665102"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184665102" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184665102">(Jan 02 2020 at 16:49)</a>:</h4>
<p><span class="user-mention" data-user-id="219211">@Jack Wrenn</span> </p>
<blockquote>
<p>Huh. Regarding <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/73" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/73">#73</a>, I find it very surprising that there could be a valid bit pattern for a union <code>T</code> that wasn't a valid bit pattern for any of <code>T</code>'s variants.</p>
</blockquote>
<p>That is explicitly desired and by design; the OP of <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/73" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/73">https://github.com/rust-lang/unsafe-code-guidelines/issues/73</a> has a motivating use-case for allowing bit patterns in a union that none of the variants allow.</p>



<a name="184665174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184665174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184665174">(Jan 02 2020 at 16:50)</a>:</h4>
<p>As per <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/73#issuecomment-570259312" target="_blank" title="https://github.com/rust-lang/unsafe-code-guidelines/issues/73#issuecomment-570259312">this comment</a> by <span class="user-mention" data-user-id="120791">@RalfJ</span>, unions do not inherently have any validity constraints. This means that we will have to require the users to opt-in to allow safe union transmute (when transmuting from a union to a non-union type)</p>



<a name="184665386"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184665386" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184665386">(Jan 02 2020 at 16:53)</a>:</h4>
<blockquote>
<p><del>Yeah, that's going to be slightly inconvenient to work around, but nothing major.</del> (I'd love to see an RFC for safely accessing the discriminants of non-fieldless variants!)</p>
<p>EDIT: That's going to be a pain to work around. It's not a theoretical limitation or anything, there's just no easy way to get the discriminant out of a variant without constructing an instance of the variant. I have an idea of how to do it, but it's a bunch of dreadful extra work on the automatic derive that I'm not eager to do tonight. :(</p>
</blockquote>
<p>also AFAIK the discriminant of dataful variants is entirely unspecified in both value and representation, so code relying on it or messing with it in any way is probably incorrect. I am not an export on representation details though, so maybe more things are fixed than I know. but please be extremely conservative around enums and only assume things that are explicitly RFC'd! Notice that the unsafe-code-guidelines repo is <em>not</em> RFC'd.</p>



<a name="184665530"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184665530" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184665530">(Jan 02 2020 at 16:55)</a>:</h4>
<p>ah and while we are speaking about unions, one of the things that is not specified for them is the start offset of the fields. for non-<code>repr(C)</code> unions, fields <em>are</em> allowed to be at non-0 offset.</p>



<a name="184665911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184665911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184665911">(Jan 02 2020 at 17:00)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span>  We are only dealing with <code>repr(C)</code> types, not even attempting anything on <code>repr(Rust)</code> types. Right now <code>enum</code>'s <code>repr(C)</code> representation is guaranteed by <a href="https://rust-lang.github.io/rfcs/2195-really-tagged-unions.html" target="_blank" title="https://rust-lang.github.io/rfcs/2195-really-tagged-unions.html">RFC#2195</a></p>



<a name="184666166"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184666166" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184666166">(Jan 02 2020 at 17:03)</a>:</h4>
<p>oh I see. yes that guarantees many things.</p>



<a name="184731951"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184731951" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184731951">(Jan 03 2020 at 13:13)</a>:</h4>
<p><span class="user-mention" data-user-id="219211">@Jack Wrenn</span> <span class="user-mention" data-user-id="202379">@Yato</span> Just catching up now. Very, very cool! I think this type of approach has a lot of promise. I'm guessing one of the biggest issues would be error messages. One extra downside one considering this as a possibility for inclusion in the std lib is that such an approach doesn't really have any precedence in the std lib. Would it be considerable to magical?</p>



<a name="184733511"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184733511" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184733511">(Jan 03 2020 at 13:34)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> <span class="user-mention" data-user-id="132920">@gnzlbg</span> <span class="user-mention" data-user-id="202379">@Yato</span> <span class="user-mention" data-user-id="219211">@Jack Wrenn</span> I know I've asked this before, but I'd like to collect use cases for the motivation for this feature. My main motivating use case is viewing bytes in a structured way for parsing network protocols in an extremely efficient way. As such a feature that allowed <code>[u8; size_of::&lt;T&gt;]</code> to <code>T</code> transmutes (when the array is well aligned) would probably be sufficient for me. I personally don't really need arbitrary casting between byte compatible types. </p>
<p>The other motivation I've seen is from <span class="user-mention" data-user-id="132920">@gnzlbg</span> around packing and unpacking of simd types to and from arrays (of floating points). I don't know enough about simd to fully understand this use case but if you're using simd instructions I can understand why performance is a concern. </p>
<p>What are some other use cases?</p>



<a name="184733771"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184733771" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184733771">(Jan 03 2020 at 13:37)</a>:</h4>
<p><span class="user-mention" data-user-id="224872">@Ryan Levick</span> I think my RFC had a collection of examples at the beginning.</p>



<a name="184733792"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184733792" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184733792">(Jan 03 2020 at 13:38)</a>:</h4>
<p>Feel free to extract those and put them wherever they might be more easily accessible.</p>



<a name="184733861"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184733861" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184733861">(Jan 03 2020 at 13:38)</a>:</h4>
<p>Compiling a collection of examples of things that we do want to support (and why) would be useful to check whether any design satisfies the constraints.</p>



<a name="184734057"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734057" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734057">(Jan 03 2020 at 13:41)</a>:</h4>
<p><span class="user-mention" data-user-id="132920">@gnzlbg</span> The examples feel a bit abstract to me. I'm looking for more higher level descriptions of use cases.</p>



<a name="184734158"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734158" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734158">(Jan 03 2020 at 13:43)</a>:</h4>
<p>Ah ok.</p>



<a name="184734172"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734172" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734172">(Jan 03 2020 at 13:43)</a>:</h4>
<p>The SIMD example is just a sub-case of doing type-punning.</p>



<a name="184734235"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734235" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734235">(Jan 03 2020 at 13:44)</a>:</h4>
<p>That's pretty much what you are doing with network data, file data, or any other example as well.</p>



<a name="184734251"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734251" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734251">(Jan 03 2020 at 13:44)</a>:</h4>
<p>So I suppose you are looking more for examples of useful type punning ?</p>



<a name="184734314"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734314" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734314">(Jan 03 2020 at 13:45)</a>:</h4>
<p>Yes to prove that we need general type punning capabilities and not specialized ones.</p>



<a name="184734356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734356">(Jan 03 2020 at 13:46)</a>:</h4>
<p>The <code>union</code> RFC might also be a good place to search for those. Another example is, e.g., comparing floating-point numbers for equality based on ULPs, using e.g. a pointer address as an <code>usize</code> hash, etc.</p>



<a name="184734413"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734413" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734413">(Jan 03 2020 at 13:47)</a>:</h4>
<p>Some of these are already supported in safe Rust via <code>as</code>, e.g., in the language reference, <code>thin_ptr as usize</code> is guaranteed to not "modify" the bits of the pointer in any way.</p>



<a name="184734485"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734485" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734485">(Jan 03 2020 at 13:48)</a>:</h4>
<p>or <code>0_isize as usize</code></p>



<a name="184734502"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734502" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734502">(Jan 03 2020 at 13:48)</a>:</h4>
<p>So there is a certain degree of "safe transmutes" (bit preserving type conversions) in the language already.</p>



<a name="184734536"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734536" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734536">(Jan 03 2020 at 13:49)</a>:</h4>
<p>I see the safe transmute RFC goal as generalizing those for user-defined types.</p>



<a name="184734657"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734657" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734657">(Jan 03 2020 at 13:50)</a>:</h4>
<p>One reason I'm asking for use cases is whether we can justify things like transmuting for types that require validation (e.g, bool). Is the complexity of supporting such transmutes worth it?</p>



<a name="184734664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734664">(Jan 03 2020 at 13:50)</a>:</h4>
<p>e.g. why is <code>0_isize as usize</code> safe, but <code>(0_isize, 0_isize) as (usize, usize)</code> require an <code>unsafe transmute</code> ?</p>



<a name="184734739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734739">(Jan 03 2020 at 13:51)</a>:</h4>
<p><span class="user-mention" data-user-id="224872">@Ryan Levick</span> good question, my RFC supports that through a different API (a different trait), which does not necessarily need to be part of the first version of the RFC</p>



<a name="184734753"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734753" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734753">(Jan 03 2020 at 13:51)</a>:</h4>
<p>I don't recall what the safe-transmute v2 RFC did</p>



<a name="184734829"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734829" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734829">(Jan 03 2020 at 13:52)</a>:</h4>
<p>but that RFC allowed transmuting types of different sizes, so if you want that, you need some kind of validation</p>



<a name="184734843"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734843" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734843">(Jan 03 2020 at 13:53)</a>:</h4>
<p>e.g. to transmute a fat <code>&amp;[T]</code> into a thin <code>&amp;[T; N]</code></p>



<a name="184734874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184734874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184734874">(Jan 03 2020 at 13:53)</a>:</h4>
<p>the type of validation you need for that isn't that different of the one required for <code>bool</code> IIRC</p>



<a name="184735000"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735000" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735000">(Jan 03 2020 at 13:54)</a>:</h4>
<p>So I guess my opinion is that I don't know if it is worth it to allow transmutes that require validation, but if we do, then it probably isn't worth it to support some validations but not others.</p>



<a name="184735049"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735049" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735049">(Jan 03 2020 at 13:55)</a>:</h4>
<p>Yea I agree that any mechanism that supports validation would allow for arbitrary validation</p>



<a name="184735126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735126">(Jan 03 2020 at 13:56)</a>:</h4>
<p>The SIMD case could benefit from validation support, e.g., we have SIMD vectors of bools, that people want to transmute from/to byte vectors</p>



<a name="184735146"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735146" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735146">(Jan 03 2020 at 13:56)</a>:</h4>
<p><code>bool -&gt; u8</code> is ok, but <code>u8 -&gt; bool</code> requires validation, and so does transmuting a <code>u8xN -&gt; boolxN</code></p>



<a name="184735162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735162">(Jan 03 2020 at 13:57)</a>:</h4>
<p>IIRC <code>packed_simd</code> currently uses <code>TryFrom</code> for those where <code>TryFrom</code> makes sense</p>



<a name="184735282"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735282" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735282">(Jan 03 2020 at 13:58)</a>:</h4>
<p>FYI: here's a WIP version of v3 of the safe-transmute proposal. It's largely unfinished but the reference guide section is mostly complete: <a href="https://gist.github.com/rylev/f0c103340d81f3ce9237184ed8e7abe6" target="_blank" title="https://gist.github.com/rylev/f0c103340d81f3ce9237184ed8e7abe6">https://gist.github.com/rylev/f0c103340d81f3ce9237184ed8e7abe6</a></p>



<a name="184735347"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735347" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735347">(Jan 03 2020 at 13:59)</a>:</h4>
<p>It would be nice to collect at this into a document of what the current state is. I'd like for <span class="user-mention" data-user-id="219211">@Jack Wrenn</span>'s proposal to settle a bit and for us to see how that fits into this.</p>



<a name="184735650"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735650" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735650">(Jan 03 2020 at 14:03)</a>:</h4>
<p>Glad to have inspired some thought! I wouldn't call typic a proposal per se, but a demonstration that when Rust's can reason about layouts at inference time, really powerful static guarantees are possible. Implementing this as a library has downsides (like error messages), so there might be a case for having rustc reason 'natively' about layouts.</p>
<p>My motivation is that I view <code>transmute</code> as a soundness footgun. If Rust can improve it's safety guarantees without incurring a runtime cost, it should—and we now know that it can! We can also improve the expressivity of <code>transmute</code>, removing it's unique limitation of not being usable in generic contexts.</p>
<p>My approach (or actually extending the type system to reason about layout natively) also creates an executable semantics of Rust's layout guarantees, which is valuable to have.</p>



<a name="184735983"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184735983" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184735983">(Jan 03 2020 at 14:08)</a>:</h4>
<p><span class="user-mention" data-user-id="219211">@Jack Wrenn</span> thanks for providing some background on your motivation. I think it's fair to say that while we should consider type level reasoning about type layout, but that we shouldn't necessarily expect a _full_ proposal on a safe transmute feature from you (though of course we're happy to have your input and help with that!).</p>



<a name="184736295"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184736295" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184736295">(Jan 03 2020 at 14:13)</a>:</h4>
<p>I wonder who the right person is to talk to about the viability of type level constraints as a solution that is likely to be accepted into the std lib. Perhaps <span class="user-mention" data-user-id="116009">@nikomatsakis</span> has some ideas?<br>
Niko, the tl;dr is that <span class="user-mention" data-user-id="219211">@Jack Wrenn</span> has written a proof of concept that allows encoding of a type's layout in the type system (as a trait) such that at the type level we can tell whether two types have compatible layouts. Besides talking with <span class="user-mention" data-user-id="239881">@Josh Triplett</span> about this from the lang team's perspective, is there a person from the compiler team who would be good to talk to about the viability of such an approach to ensure safe transmute?</p>



<a name="184736869"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184736869" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184736869">(Jan 03 2020 at 14:22)</a>:</h4>
<p>Another issue is performance, as types scale up, the performance of this method dies (but only for really large types). For example, converting between 2 4-kilobyte types took about a minute to compile. If there are any errors you get a full screenful of a type.<br>
I think that Rust can do better, especially wrt error messages and performance. Now a 4-kilobyte type is huge, so this may not be a problem, but doing lots of these checked transmutes could add up in the same way.</p>



<a name="184737141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184737141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184737141">(Jan 03 2020 at 14:26)</a>:</h4>
<p>I personally would not want the type based checked transmutes in std, because it is really complex and subtle. It be far more reliable and maintainable if these computations were baked into the compiler.</p>



<a name="184737870"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184737870" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184737870">(Jan 03 2020 at 14:36)</a>:</h4>
<blockquote>
<p>I wonder who the right person is to talk to about the viability of type level constraints as a solution that is likely to be accepted into the std lib. Perhaps @nikomatsakis has some ideas?</p>
</blockquote>
<p>I can imagine how to do this reliably using traits, but haven't looked at typic. I can't imagine a way of doing this reliably and efficiently as a library.</p>



<a name="184737890"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184737890" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184737890">(Jan 03 2020 at 14:37)</a>:</h4>
<p><span class="user-mention" data-user-id="219211">@Jack Wrenn</span> do you have any compile-time benchmarks for <code>typic</code> ?</p>



<a name="184737919"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184737919" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184737919">(Jan 03 2020 at 14:37)</a>:</h4>
<p>e.g. we used to have benchmarks for meta-programming like this in C++, for example, in <a href="http://metaben.ch/" target="_blank" title="http://metaben.ch/">http://metaben.ch/</a></p>



<a name="184737993"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184737993" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184737993">(Jan 03 2020 at 14:38)</a>:</h4>
<p>In a nutshell one just needs to automatically generate a file containing two types, and performing a typic conversions, and measure the compile-time.</p>



<a name="184738028"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184738028" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184738028">(Jan 03 2020 at 14:38)</a>:</h4>
<p>You then increase the size of these types, e.g., by adding more fields, and plot the compile-time as a function of, e.g., the type fields.</p>



<a name="184738043"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184738043" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184738043">(Jan 03 2020 at 14:39)</a>:</h4>
<p>You can then also add more types, and plot the compile-times as a functions of the types using <code>typic</code></p>



<a name="184738212"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184738212" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184738212">(Jan 03 2020 at 14:40)</a>:</h4>
<p>Not yet. If you don't transmute between two types, you shouldn't pay any penalty for computing the layout of those types.</p>
<p>My implementation aims for simplicity in the low level representation, not efficiency. <span class="user-mention" data-user-id="202379">@Yato</span> followed up with a more efficient representation without too much increased complexity.</p>
<p>I like your benchmarking idea!</p>



<a name="184738235"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184738235" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184738235">(Jan 03 2020 at 14:41)</a>:</h4>
<p>I've thought about writing a tool to "hammer" the rust compiler, by allowing to easily specify production rules for tests like these, but never got the time to do it. There are many language features for which compile-times currently explode once you add more cases (e.g. a <code>match 0_i32 { 0 =&gt; ..., 1 =&gt; ..., ... i32::MAX =&gt; ... }</code> where compile-times grow as a function of the match arms in a non-linear way).</p>



<a name="184750492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184750492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184750492">(Jan 03 2020 at 17:16)</a>:</h4>
<p>I'm not sure if my way is more efficient, just that it has less special casing.</p>



<a name="184757094"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/184757094" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#184757094">(Jan 03 2020 at 18:44)</a>:</h4>
<p>(What happened to your last list of needs? keep this one in a safe place this time :P )</p>
<p>I've had the following general needs:</p>
<ul>
<li><strong>owned casting (T -&gt; U):</strong> Generally used with "math stuff" like f32/u32/i32 mixing, or SIMD versions of the same, or arrays, etc.</li>
<li><strong>slice casting (&amp;[T] -&gt; &amp;[U], with appropriate length change if T and U aren't the same size, and with the &amp;mut variant as well):</strong> Often needed for things like data format stuff as you move it between places. <code>include_bytes!</code> (gives <code>&amp;[u8]</code>) to SPIRV (needs to be <code>&amp;[u32]</code>), or uploading a texture (in <code>&amp;[RGBA8]</code>) to the graphics card (takes <code>&amp;[u8]</code>), or string stuff (in <code>&amp;[u8]</code>) as you send it out to FFI (<code>&amp;[c_char]</code>).</li>
<li><strong>Lone reference to and from slices (<code>&amp;T</code> -&gt; <code>&amp;[U]</code> and <code>&amp;[U]</code> -&gt; <code>&amp;T</code>)</strong> This is the use case you needed, which I didn't need until very recently but have bumped into myself.</li>
</ul>



<a name="185336572"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185336572" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185336572">(Jan 10 2020 at 18:24)</a>:</h4>
<blockquote>
<blockquote>
<p>I wonder who the right person is to talk to about the viability of type level constraints as a solution that is likely to be accepted into the std lib. Perhaps @nikomatsakis has some ideas?</p>
</blockquote>
<p>I can imagine how to do this reliably using traits, but haven't looked at typic. I can't imagine a way of doing this reliably and efficiently as a library.</p>
</blockquote>
<p>Incidentally, I think I've encountered an obstacle in my implementation of enums. In short, there's one case where I need to encode a type-level <code>Filter</code> operation. However, I don't know how to that without overlapping implementations. Overlapping implementations are supported with <code>#[marker]</code>, but _not_ on traits with associated types. A <code>Filter</code>-like trait needs an associated type to encode its output.</p>
<p>A brief experiment suggests that chalk is already capable of expressing this.</p>



<a name="185356120"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185356120" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185356120">(Jan 10 2020 at 22:03)</a>:</h4>
<p>Actually, disregard the above! I think I found a workaround.</p>



<a name="185396879"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185396879" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185396879">(Jan 11 2020 at 16:54)</a>:</h4>
<p>For the curious, I've started modeling the type-level compatibility checking rules with Prolog. Prolog is really a fantastic way to experiment with typelevel programming in Rust. Rust's type system is very similar to Prolog, and Prolog predicates can be written in a way that admits straight-forward translation to Rust code. The repo is here: <a href="https://github.com/jswrenn/typic-pl" target="_blank" title="https://github.com/jswrenn/typic-pl">https://github.com/jswrenn/typic-pl</a></p>



<a name="185403468"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185403468" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185403468">(Jan 11 2020 at 20:09)</a>:</h4>
<p>I'm nervous about this being computed at compile time every build.</p>
<p>How have the build times been with this approach?</p>



<a name="185404781"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185404781" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185404781">(Jan 11 2020 at 20:52)</a>:</h4>
<p>I haven't benchmarked anything, but in the process of developing and testing typic, compilation has been basically instantaneous. There's a few costs to consider:</p>
<p>The library itself:</p>
<ol>
<li><code>typic</code> itself builds nearly instantly, but relies on <code>typic-derive</code></li>
<li><code>typic-derive</code> requires <code>syn</code>, which has significant one-off build time.</li>
</ol>
<p>Clients using the library:</p>
<ol>
<li>For types marked with <code>#[typic::repr(C)]</code>, a trait implementation is generated with an associated type that corresponds to the high-level structure of that type. It's akin to <a href="https://docs.rs/frunk/0.3.1/frunk/generic/trait.Generic.html" target="_blank" title="https://docs.rs/frunk/0.3.1/frunk/generic/trait.Generic.html"><code>frunk::Generic</code></a>. This is just a syntactic transformation of the type. There is no type-level computation happening yet.</li>
<li>The low-level representations of types are only computed if the user tries to transmute between them. How expensive this is depends on the complexity of the types. For small types, it's basically instantaneous.</li>
</ol>



<a name="185404933"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185404933" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185404933">(Jan 11 2020 at 20:56)</a>:</h4>
<p>That last item is really the only expensive operation. The good news is that it's paid on-demand, <em>only</em> for the types you try to transmute between.</p>
<p>I'm unsure to what extent this cost is paid on <em>every</em> build. It might be the case that incremental compilation caches most of the computation. I'll have to look into it.</p>



<a name="185458719"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185458719" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185458719">(Jan 13 2020 at 01:21)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> </p>
<div class="codehilite"><pre><span></span><span class="cp">#[typic::repr(C)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">T6</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">a</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">b</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">c</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">d</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">e</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">f</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="nc">T6</span><span class="o">&lt;</span><span class="kt">u64</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T6</span><span class="o">&lt;</span><span class="kt">u64</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">use</span><span class="w"> </span><span class="n">typic</span>::<span class="n">transmute</span>::<span class="n">TransmuteFrom</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">T8</span>::<span class="n">transmute_from</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>took 7.72 s to build on my computer (just this, nothing else). So performance is definitely a concern.</p>



<a name="185458829"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185458829" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185458829">(Jan 13 2020 at 01:24)</a>:</h4>
<p>Incremental compilation helps, but Rust need to redo all the work <em>for every call to <code>transmute_from</code></em></p>



<a name="185459345"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185459345" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185459345">(Jan 13 2020 at 01:43)</a>:</h4>
<p>That said, I just tested my version, and a the equivalent code (shown below) built in under a second</p>
<div class="codehilite"><pre><span></span><span class="cp">#[chtrans::repr(C)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">T6</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">a</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">b</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">c</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">d</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">e</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">f</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="nc">T6</span><span class="o">&lt;</span><span class="kt">u64</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">T6</span><span class="o">&lt;</span><span class="kt">u64</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">use</span><span class="w"> </span><span class="n">chtrans</span>::<span class="n">Reinterpret</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="p">.</span><span class="n">reinterp_into</span><span class="p">()</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="185459406"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185459406" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185459406">(Jan 13 2020 at 01:45)</a>:</h4>
<p>(although I did find out that I didn't support generic types till now, so there's that)</p>



<a name="185459500"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185459500" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185459500">(Jan 13 2020 at 01:48)</a>:</h4>
<p>Just tried to push it a bit, and I broke the default recursion limit :)</p>
<p>This took ~9 s</p>
<div class="codehilite"><pre><span></span><span class="cp">#![recursion_limit=</span><span class="s">&quot;10000&quot;</span><span class="cp">]</span><span class="w"></span>

<span class="cp">#[chtrans::repr(C)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">T4</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">a</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">b</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">c</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">d</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">e</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">f</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">g</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">h</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="cp">#[chtrans::repr(C)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">T8</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">a</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">b</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">c</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">d</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">e</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">f</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">g</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">h</span>: <span class="nc">T</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="nc">T8</span><span class="o">&lt;</span><span class="n">T4</span><span class="o">&lt;</span><span class="kt">u64</span><span class="o">&gt;&gt;</span><span class="p">,</span><span class="w"> </span><span class="p">()</span>: <span class="p">())</span><span class="w"> </span>-&gt; <span class="nc">T4</span><span class="o">&lt;</span><span class="n">T8</span><span class="o">&lt;</span><span class="kt">u64</span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">use</span><span class="w"> </span><span class="n">chtrans</span>::<span class="n">Reinterpret</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="p">.</span><span class="n">reinterp_into</span><span class="p">()</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="185459723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185459723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185459723">(Jan 13 2020 at 01:56)</a>:</h4>
<p>the largest I'm willing to try took ~27s</p>
<div class="codehilite"><pre><span></span><span class="cp">#[chtrans::repr(C)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Big</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">_a</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">1</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">_b</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">2</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">_c</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">_d</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">4</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">_e</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">5</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">_f</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">6</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">_g</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">7</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">_h</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">8</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">a</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">9</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">b</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">10</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">c</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">11</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">d</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">12</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">e</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">13</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">f</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">14</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">g</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">15</span><span class="p">],</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="n">h</span>: <span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">16</span><span class="p">],</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="nc">Big</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Big</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">use</span><span class="w"> </span><span class="n">chtrans</span>::<span class="n">Reinterpret</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="p">.</span><span class="n">reinterp_into</span><span class="p">()</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>Rust seems to be good at caching results sometimes, so having a lot of different types helps kill build times.</p>



<a name="185554754"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185554754" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185554754">(Jan 14 2020 at 00:50)</a>:</h4>
<p>Yikes! Are there any mechanisms for tracing trait resolution? I'd be very interested to know how the time is being spent.</p>



<a name="185562729"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185562729" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185562729">(Jan 14 2020 at 03:44)</a>:</h4>
<p>I am not aware of any</p>



<a name="185932308"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185932308" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185932308">(Jan 17 2020 at 16:33)</a>:</h4>
<p>Trait resolution is just very poorly suited for this</p>



<a name="185932356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185932356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185932356">(Jan 17 2020 at 16:33)</a>:</h4>
<p>This problem is common enough that it deserves a good solution</p>



<a name="185973074"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/185973074" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#185973074">(Jan 18 2020 at 01:14)</a>:</h4>
<p>Is there a specific proposal to go with that?</p>



<a name="186098849"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/186098849" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#186098849">(Jan 20 2020 at 12:51)</a>:</h4>
<p>There is the <code>Compatible&lt;T&gt;</code> rfc</p>



<a name="186098931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/186098931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#186098931">(Jan 20 2020 at 12:52)</a>:</h4>
<p>and the safe-transmute v2/v3 rfcs</p>



<a name="186099087"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/186099087" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#186099087">(Jan 20 2020 at 12:54)</a>:</h4>
<p>but the transitive closure in the <code>Compatible&lt;T&gt;</code> RFC only works for transmuting types that have the same size</p>



<a name="186099158"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/186099158" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#186099158">(Jan 20 2020 at 12:55)</a>:</h4>
<p>I don't think there is a good solution with transitive closure for transmuting types of different sizes into each other</p>



<a name="186099176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/186099176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#186099176">(Jan 20 2020 at 12:55)</a>:</h4>
<p>although there are some</p>



<a name="186099302"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/186099302" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#186099302">(Jan 20 2020 at 12:57)</a>:</h4>
<p>e.g. one could make the <code>TryCompatible&lt;T&gt;</code> trait in the compatible-RFC have transitive closure, by eliminating the associated error type</p>



<a name="186099393"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/186099393" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#186099393">(Jan 20 2020 at 12:58)</a>:</h4>
<p>at the cost of loosing the ability to specify custom error conditions</p>



<a name="187496621"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187496621" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187496621">(Feb 05 2020 at 21:25)</a>:</h4>
<p>I was curious how far a Safer Transmute RFC could get in which every example was explorable with Typic, and the answer is pretty far: <a href="https://github.com/jswrenn/typic/blob/master/0000-safer_transmute.md" target="_blank" title="https://github.com/jswrenn/typic/blob/master/0000-safer_transmute.md">https://github.com/jswrenn/typic/blob/master/0000-safer_transmute.md</a></p>
<p>All of the guidance in that document is implemented in Typic. The examples that ought to work <em>actually</em> compile and run. The examples that ought to fail <em>actually</em> produce compile errors.</p>
<p>(Well, except that the automatic <code>Transparent</code> impl currently happens a little more conservatively than I've described in that document: the implementation requires that all fields are <code>pub</code>, not <em>merely</em> that they have visibility greater than or equal to their parent type, as specified. I'll fix that tomorrowish.)</p>



<a name="187497257"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187497257" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187497257">(Feb 05 2020 at 21:32)</a>:</h4>
<p><span class="user-mention" data-user-id="202379">@Yato</span> The new implementation is also <em>much</em> faster. Your <code>Big</code> testcase now takes under a second on my laptop. With incremental builds thereafter, I don't notice any slowdown at all.</p>



<a name="187655479"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187655479" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187655479">(Feb 07 2020 at 16:40)</a>:</h4>
<p><span class="user-mention" data-user-id="219211">@Jack Wrenn</span>  Cool! What was the big slowdown?</p>



<a name="187656308"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187656308" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187656308">(Feb 07 2020 at 16:51)</a>:</h4>
<p>Looks like you went through a big rewrite recently, can I get a brief summary of what changed? It looks like you moved away from frunk into some custom type encodings like I did, but it's a big change and I'm not sure how it all fits together in my brief look at it.</p>



<a name="187660733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187660733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187660733">(Feb 07 2020 at 17:34)</a>:</h4>
<p><span class="user-mention" data-user-id="202379">@Yato</span> The major representational change is that rather than representing type layouts as an <code>HList</code> of one-byte slots, the leaves of the new low-level representation have both a <code>Kind</code> and a <code>Size</code>.</p>
<p>So, eight adjacent padding bytes is no longer an <code>HList</code> of eight <code>Uninitialized</code> slots. It's now one slot with <code>Kind=Uninitialized</code> and <code>Size=U8</code>. </p>
<p>I'm guessing this change is responsible for the speedup, but I never actually traced trait resolution on the initial version, so I can't be absolutely sure.</p>



<a name="187664845"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187664845" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187664845">(Feb 07 2020 at 18:17)</a>:</h4>
<p>As far as the public API goes, I refocused typic on strictly on <em>infallible</em> conversions. The public API of the crate exactly models what I think the public API of an initial, general, safe transmute RFC should be:</p>
<ul>
<li>The function <a href="https://docs.rs/typic/latest/typic/fn.transmute_safe.html" target="_blank" title="https://docs.rs/typic/latest/typic/fn.transmute_safe.html"><code>transmute_safe</code></a> and traits <a href="https://docs.rs/typic/latest/typic/trait.TransmuteInto.html" target="_blank" title="https://docs.rs/typic/latest/typic/trait.TransmuteInto.html"><code>TransmuteInto</code></a> and <a href="https://docs.rs/typic/latest/typic/trait.TransmuteFrom.html" target="_blank" title="https://docs.rs/typic/latest/typic/trait.TransmuteFrom.html"><code>TransmuteFrom</code></a>, providing completely safe transmutation.</li>
<li>The function <a href="https://docs.rs/typic/latest/typic/fn.transmute_sound.html" target="_blank" title="https://docs.rs/typic/latest/typic/fn.transmute_sound.html"><code>transmute_sound</code></a>, which is a soundness-enforcing (but still unsafe) successor to <code>mem::transmute</code>.</li>
</ul>
<p>A <em>general</em> solution for <em>fallible</em> conversions is much trickier, because error reporting is hard to get right.</p>



<a name="187686578"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187686578" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187686578">(Feb 07 2020 at 22:33)</a>:</h4>
<p>What's so hard to get right?</p>



<a name="187688317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187688317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187688317">(Feb 07 2020 at 23:00)</a>:</h4>
<p>Let's say we want to transmute from <code>u16</code> to <code>Constrained</code>:</p>
<div class="codehilite"><pre><span></span><span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Constrained</span><span class="p">(</span><span class="n">NonZeroU8</span><span class="p">,</span><span class="w"> </span><span class="kt">bool</span><span class="p">);</span><span class="w"></span>
</pre></div>


<p>On a little-endian system, this is only a valid transmutation if our <code>u16</code> is greater than 0 and less than 512. In all other cases, a general-purpose, fallible, sound transmuter should be able to report which bytes of our source type violated the layout of the destination type.</p>
<p>A general-purpose, fallible, <em>safe</em> transmuter should be able to communicate why user-defined invariants are violated, too. (E.g., if <code>Constrained</code> also required that it's first field was an odd number.)</p>



<a name="187727677"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187727677" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Shnatsel <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187727677">(Feb 08 2020 at 19:01)</a>:</h4>
<p>Is the granularity of "alignment", "size" and "type invariants" not enough?</p>



<a name="187727803"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187727803" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Shnatsel <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187727803">(Feb 08 2020 at 19:05)</a>:</h4>
<p>I don't think you can reasonably report what type invariant exactly was broken in code that's this generic.</p>



<a name="187727845"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187727845" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Shnatsel <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187727845">(Feb 08 2020 at 19:06)</a>:</h4>
<p>I've just been looking into this in the context of <a href="https://gitlab.freedesktop.org/zeenix/zbus/" target="_blank" title="https://gitlab.freedesktop.org/zeenix/zbus/">https://gitlab.freedesktop.org/zeenix/zbus/</a> and that's the only errors that any code I can imagine really cares to distinguish between. If it's an alignment problem, the fix is just copy the thing and make the alignment correct; if it's a size or broken type invariant problem, then we reject the input as invalid. That's it.</p>



<a name="187727852"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187727852" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Shnatsel <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187727852">(Feb 08 2020 at 19:06)</a>:</h4>
<p>OTOH I like the idea of keeping the scope contained and getting infallible conversions right first, then experimenting with fallible ones</p>



<a name="187746743"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/187746743" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Yato <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#187746743">(Feb 09 2020 at 06:08)</a>:</h4>
<p>Yes, encoding the size would speed things up, especially because typenum has O(log n) operations as opposed to mine at O(n).</p>
<p>I agree that we should only focus on infallible conversions as a start.</p>



<a name="190096666"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190096666" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190096666">(Mar 09 2020 at 17:40)</a>:</h4>
<p>So, I'm thinking about how bit validity interacts with mutation.</p>
<p>Consider these two type definitions:</p>
<div class="codehilite"><pre><span></span><span class="k">struct</span> <span class="nc">Foo</span><span class="p">(</span><span class="k">pub</span><span class="w"> </span><span class="n">NonZeroU8</span><span class="p">);</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Bar</span><span class="p">(</span><span class="k">pub</span><span class="w"> </span><span class="kt">u8</span><span class="p">);</span><span class="w"></span>
</pre></div>


<p>Given these types,</p>
<ul>
<li><code>Foo</code> → <code>Bar</code> is safe.</li>
<li><code>&amp;Foo</code> → <code>&amp;Bar</code> is safe.</li>
<li><code>&amp;mut Foo</code> → <code>&amp;mut Bar</code> is unsafe:</li>
</ul>
<div class="codehilite"><pre><span></span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">foo</span>: <span class="nc">Foo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">...;</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">bar</span><span class="w"> </span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">Bar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">transmute</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">foo</span><span class="p">);</span><span class="w"></span>
<span class="w">  </span><span class="n">bar</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="n">assert_eq</span><span class="o">!</span><span class="p">(</span><span class="n">foo</span><span class="p">.</span><span class="mf">0.</span><span class="n">get</span><span class="p">(),</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span><span class="w"> </span><span class="c1">// ack!!!</span>
</pre></div>


<p>This suggests a rule: bit validity can be widened with a value-to-value transmute, but is totally invariant for a mutable-reference-to-mutable-reference transmute.</p>



<a name="190096708"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190096708" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190096708">(Mar 09 2020 at 17:41)</a>:</h4>
<p>Except, now let's consider:</p>
<div class="codehilite"><pre><span></span><span class="k">struct</span> <span class="nc">Foo</span><span class="p">(</span><span class="k">pub</span><span class="w"> </span><span class="n">NonZeroU8</span><span class="p">);</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Bar</span><span class="p">(</span><span class="k">pub</span><span class="w"> </span><span class="n">AtomicU8</span><span class="p">);</span><span class="w"></span>
</pre></div>


<p>Given those types,</p>
<ul>
<li><code>Foo</code> → <code>Bar</code> is safe.</li>
<li><code>&amp;Foo</code> → <code>&amp;Bar</code> is <strong>unsafe</strong>:</li>
</ul>
<div class="codehilite"><pre><span></span><span class="kd">let</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Foo</span><span class="p">(</span><span class="n">NonZeroU8</span>::<span class="n">new</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="n">unwrap</span><span class="p">());</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="n">bar</span>: <span class="kp">&amp;</span><span class="nc">Bar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">core</span>::<span class="n">mem</span>::<span class="n">transmute</span><span class="p">(</span><span class="o">&amp;</span><span class="n">foo</span><span class="p">);</span><span class="w"></span>
<span class="w">  </span><span class="n">bar</span><span class="p">.</span><span class="mf">0.</span><span class="n">store</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">Ordering</span>::<span class="n">Relaxed</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="n">assert_eq</span><span class="o">!</span><span class="p">(</span><span class="n">foo</span><span class="p">.</span><span class="mf">0.</span><span class="n">get</span><span class="p">(),</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span><span class="w"> </span><span class="c1">// ack!!!</span>
</pre></div>


<p>I'm not really sure what rule is suggested by this.</p>



<a name="190098005"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190098005" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190098005">(Mar 09 2020 at 17:54)</a>:</h4>
<p>A very coarse rule is that validity is invariant whenever references (shared or unique) are involved.</p>
<p>I think the <strong>actual</strong> rule is something like: <code>&amp;T</code> → <code>&amp;U</code> is safe only if <code>U</code> does not directly or transitively contain any <code>UnsafeCell</code>s.</p>



<a name="190098360"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190098360" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Liebow-Feeser <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190098360">(Mar 09 2020 at 17:57)</a>:</h4>
<p>As for the first point, the rule I use in <code>zerocopy</code> is that <code>&amp;mut Foo -&gt; &amp;mut Bar</code> requires that <code>Foo -&gt; Bar</code> and <code>Bar -&gt; Foo</code> since the reference allows you to both view a <code>Foo</code> as a <code>Bar</code> and also store a <code>Bar</code> in the location that may be later viewed as a <code>Foo</code>. There are more constraints besides (as you've pointed out with your atomic example), but those requirements exist at a minimum.</p>



<a name="190099857"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190099857" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190099857">(Mar 09 2020 at 18:12)</a>:</h4>
<p>Typic used a similar rule for a while, but ultimately abandoned it, because it forbids safe transmutations between types of different sizes. Given:</p>
<div class="codehilite"><pre><span></span><span class="k">type</span> <span class="nc">A0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">0</span><span class="p">];</span><span class="w"></span>
<span class="k">type</span> <span class="nc">A9</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">9</span><span class="p">];</span><span class="w"></span>
</pre></div>


<p>...we have the following transmutations:</p>
<ol>
<li><code>A9</code> → <code>A0</code></li>
<li><code>A0</code> ↛ <code>A9</code></li>
<li><code>&amp;A9</code> → <code>&amp;A0</code></li>
<li><code>&amp;A0</code> ↛ <code>&amp;A9</code></li>
</ol>
<p>That rule eliminates transmute №3, since <code>A0</code> ↛ <code>A9</code>.</p>



<a name="190112520"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190112520" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190112520">(Mar 09 2020 at 20:12)</a>:</h4>
<p>I wouldn't say that A9 -&gt; A0 is valid in the first place</p>



<a name="190124641"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190124641" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190124641">(Mar 09 2020 at 22:26)</a>:</h4>
<p>Why not?</p>



<a name="190137406"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190137406" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190137406">(Mar 10 2020 at 02:29)</a>:</h4>
<p>I would not allow different sized owned casting</p>



<a name="190137457"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190137457" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190137457">(Mar 10 2020 at 02:30)</a>:</h4>
<p>it's relatively poorly defined and you can generally have the user reference manipulate things to get the cast they want if they really do want to truncate things</p>



<a name="190137461"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190137461" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190137461">(Mar 10 2020 at 02:31)</a>:</h4>
<p>It's maybe a bit weird, but not at all unsound. <span aria-label="shrug" class="emoji emoji-1f937" role="img" title="shrug">:shrug:</span></p>



<a name="190137575"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190137575" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190137575">(Mar 10 2020 at 02:34)</a>:</h4>
<p>On the scale of good APIs there's a small margin just above "strictly speaking sound" where the API is still a footgun</p>



<a name="190137757"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190137757" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190137757">(Mar 10 2020 at 02:38)</a>:</h4>
<p>Sure. Right now, Typic is scoped to just telling you when you're doing something unstable, unsafe, or unsound—but not unsensible.</p>



<a name="190137769"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190137769" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190137769">(Mar 10 2020 at 02:39)</a>:</h4>
<p>Although I've actually legitimately used shrinking transmutes of arrays!</p>



<a name="190138309"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190138309" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190138309">(Mar 10 2020 at 02:52)</a>:</h4>
<p>Sure, there are correct uses, but usually you should sub-slice it down to a desired size and use the sub-slice</p>



<a name="190156324"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190156324" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190156324">(Mar 10 2020 at 09:53)</a>:</h4>
<p>The cast <code>A9</code> -&gt; <code>A0</code>, in that case, seems as if it should be implemented as a conversion by reference followed by deref+Copy to me.<br>
But it makes a point, that this is not always possible and requires <code>A0: Copy</code>.</p>



<a name="190195094"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190195094" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190195094">(Mar 10 2020 at 16:40)</a>:</h4>
<p>You also probably really shouldn't be transmuting non-Copy data in the first place ;P</p>



<a name="190200068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/190200068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#190200068">(Mar 10 2020 at 17:22)</a>:</h4>
<p>I've compiled a condensed introduction to what typic provides, that might be helpful: <a href="https://hackmd.io/@jswrenn/HydSGVHS8" target="_blank" title="https://hackmd.io/@jswrenn/HydSGVHS8">https://hackmd.io/@jswrenn/HydSGVHS8</a></p>



<a name="201160326"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201160326" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201160326">(Jun 17 2020 at 15:43)</a>:</h4>
<p><span class="user-mention" data-user-id="224872">@Ryan Levick</span> you <a href="https://github.com/rust-lang/lang-team/issues/26">wrote</a>:</p>
<blockquote>
<p>While it might be possible to expose friendly traits for most use cases, there will be some use cases that require complex type level programming to be understood by the user.</p>
</blockquote>
<p>What use cases are you thinking of?</p>



<a name="201161415"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201161415" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201161415">(Jun 17 2020 at 15:52)</a>:</h4>
<p>I actually was thinking of one where we could expose a simple trait. I’ll rephrase that</p>



<a name="201161712"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201161712" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201161712">(Jun 17 2020 at 15:54)</a>:</h4>
<p>I still think the sentiment stands. Typic’s approach is complicated. I’m of the personal opinion that this is necessary complexity if we want a solution that covers the largest percentage of use cases, but complexity is still a con even if it’s warranted</p>



<a name="201162283"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201162283" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201162283">(Jun 17 2020 at 15:59)</a>:</h4>
<p>I don't think it's necessary complexity to cover the widest percentage of use cases</p>



<a name="201162368"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201162368" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201162368">(Jun 17 2020 at 16:00)</a>:</h4>
<p>It's maybe necessary to get 100% of cases though</p>



<a name="201162452"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201162452" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201162452">(Jun 17 2020 at 16:00)</a>:</h4>
<p>Typic's definitely internally complicated, but I don't think the public interface is. There's just two basic traits for transmuting: <code>TransmuteFrom&lt;SrcType&gt;</code> and <code>UnsafeTransmuteFrom&lt;SrcType&gt;</code>.</p>
<p>Likewise, the method used to declare ABI guarantees will also be just two traits: <code>TransmutableFrom</code> and <code>TransmutableInto</code>.</p>
<p>One of my motivations for typic's approach was exploring whether it was possible to avoid a zoo of marker traits.</p>



<a name="201162960"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201162960" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201162960">(Jun 17 2020 at 16:04)</a>:</h4>
<p><span class="user-mention" data-user-id="219211">@Jack Wrenn</span> I agree for straight transmute this is true, but I'm hoping to also discuss other things that are related tangentially like a Zeroable marker trait</p>



<a name="201163056"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201163056" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201163056">(Jun 17 2020 at 16:04)</a>:</h4>
<p>I'm also not sure about what complexity would be needed to ensure good error messages</p>



<a name="201163815"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201163815" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201163815">(Jun 17 2020 at 16:10)</a>:</h4>
<p>I don't know if <a href="#narrow/stream/216762-project-safe-transmute/topic/mem-markers.20v0.2E1/near/198681841">this</a> is really what's conjured by the phrase "complex type level programming".</p>
<p>It's a common enough pattern that having a facade <code>Zeroable</code> trait is probably nice to have, but it's nowhere near the complexity of using frunk or nalgebra (which I think is what comes to mind when people hear "complex type level programming").</p>



<a name="201164071"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201164071" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201164071">(Jun 17 2020 at 16:13)</a>:</h4>
<p>That's fair. Does the phrase "non-trivial API" sound like a more accurate statement?</p>



<a name="201164770"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201164770" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201164770">(Jun 17 2020 at 16:18)</a>:</h4>
<p>Er, I think the public API _is_ trivial, though. Just one trait (<code>TransmuteFrom</code>) covers 90% of use cases. And you mostly don't need to think about what marker traits you need to implement, because typic does it for you.</p>
<p>Whether that's simpler is just my (rather uninformed) personal opinion. I feel like juggling many manually-implemented marker traits is more complex, but maybe it isn't. I'd be curious to here <span class="user-mention" data-user-id="132362">@Joshua Liebow-Feeser</span>'s thoughts on using zerocopy in practice.</p>



<a name="201165116"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165116" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165116">(Jun 17 2020 at 16:21)</a>:</h4>
<p>Manually implemented marker traits are so extremely simple</p>



<a name="201165172"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165172" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165172">(Jun 17 2020 at 16:21)</a>:</h4>
<p>The implementation details of Typic are definitely "much more complex" right now, but the public API isn't. </p>
<p>The type-level programming aspect of typic is an internal implementation detail. Probably a temporary one, too: if our recent const-generics experimentation is any indicator the implementation details of typic will probably get much simpler in the future by just relying solely on rustc's own layout computation.</p>



<a name="201165505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165505">(Jun 17 2020 at 16:24)</a>:</h4>
<p><span class="user-mention" data-user-id="219211">@Jack Wrenn</span> one thing is that we'd need a slightly alternative interface for opting in to transmutation than is currently used</p>



<a name="201165520"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165520" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165520">(Jun 17 2020 at 16:24)</a>:</h4>
<p>though this is a small issue</p>



<a name="201165600"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165600" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165600">(Jun 17 2020 at 16:25)</a>:</h4>
<p>For the record, I think that the best path is <em>both options</em>, implement typic style computation in the compiler that's user visible, then also make marker traits based on the typic computation</p>



<a name="201165658"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165658" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165658">(Jun 17 2020 at 16:25)</a>:</h4>
<p>That's close to what I'm thinking too.</p>



<a name="201165664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165664">(Jun 17 2020 at 16:25)</a>:</h4>
<blockquote>
<p>one thing is that we'd need a slightly alternative interface for opting in to transmutation than is currently used</p>
</blockquote>
<p>can you clarify?</p>



<a name="201165897"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165897" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165897">(Jun 17 2020 at 16:27)</a>:</h4>
<p>currently (as i understand it) people put [typic::repr(C)] on a type to make it go through the typic calculation, but if this were official then having the normal repr(C) shouldn't necessarily be all it takes to be transmutable</p>



<a name="201165967"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165967" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201165967">(Jun 17 2020 at 16:28)</a>:</h4>
<p>because that's a stability hazard, which wr have enough of already</p>



<a name="201166045"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201166045" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201166045">(Jun 17 2020 at 16:28)</a>:</h4>
<p>Oh, it's not. You also have to make all of your fields public, and declare lower and/or upper ABI bounds (via <code>TransmutableFrom</code> and <code>TransmutableInto</code>).</p>



<a name="201166740"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201166740" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jack Wrenn <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201166740">(Jun 17 2020 at 16:34)</a>:</h4>
<p>(Ooof, I really need to release more...)</p>



<a name="201169146"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201169146" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201169146">(Jun 17 2020 at 16:53)</a>:</h4>
<p>release every 6 weeks no matter what. that's the rust way!</p>



<a name="201173287"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201173287" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201173287">(Jun 17 2020 at 17:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/216762-project-safe-transmute/topic/typic/near/201165600">said</a>:</p>
<blockquote>
<p>For the record, I think that the best path is <em>both options</em>, implement typic style computation in the compiler that's user visible, then also make marker traits based on the typic computation</p>
</blockquote>
<p>I agree with this fwiw</p>



<a name="201173821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216762-project-safe-transmute/topic/typic/near/201173821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rylev <a href="https://rust-lang.github.io/zulip_archive/stream/216762-project-safe-transmute/topic/typic.html#201173821">(Jun 17 2020 at 17:28)</a>:</h4>
<p>With regards to the complexity of the API, I agree that for the normal transmute case, the public API is as simple as it can be, but the Zeroable example is more complex IMO than it would be with marker traits since the zeroable marker trait would already be provided to the user. That being said, as I said above, I think the right answer is a combination of both - marker traits provided by typic style compile time information about the type's layout</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>